home *** CD-ROM | disk | FTP | other *** search
/ SPACE 1 / SPACE - Library 1 - Volume 1.iso / program / 441 / dlibs12 / realloc.c < prev    next >
C/C++ Source or Header  |  1990-11-23  |  2KB  |  92 lines

  1. #include <stddef.h>
  2. #include <malloc.h>
  3.  
  4. #define    MAXBLK        16
  5. #define    FREE        0x00
  6. #define    USED        0x80
  7. #define    NULLBLK        0x80000000L
  8.  
  9. extern    char    *_mblk[];        /* memory heap pointers */
  10. extern    long    _msiz[];        /* memory heap sizes */
  11.  
  12. static long *unlinkblk(addr)
  13.     register long *addr;
  14. /*
  15.  *    Unlink memory block at <addr> from free memory chain.
  16.  */
  17.     {
  18.     register int i;
  19.     register long *p, *q;
  20.  
  21.     for(i=0; i<MAXBLK; ++i)
  22.         {
  23.         if((q = p = ((long *) _mblk[i])) == NULL)
  24.             continue;        /* skip unavailable blocks */
  25.         if((addr < p) || (addr > ((long *) (((char *) p)+_msiz[i]))))
  26.             continue;        /* block range check */
  27.         while(p = ((long *) *q))
  28.             {
  29.             if(p == addr)        /* found the right block */
  30.                 {
  31.                 q[0] = p[1];    /* unlink it */
  32.                 return(p);
  33.                 }
  34.             q = p + 1;
  35.             }
  36.         }
  37.     return(NULL);
  38.     }
  39.  
  40. char *realloc(addr, size)
  41.     register long *addr;
  42.     unsigned int size;
  43.     {
  44.     register long n, m, d, *p, *q;
  45.     char *lalloc();
  46.  
  47.     if(addr == NULL)
  48.         return(lalloc((long) size));
  49.     if(size == 0)
  50.         {
  51.         free(addr);
  52.         return(addr);
  53.         }
  54.     p = addr - 1;
  55.     n = p[0] & 0x00FFFFFFL;            /* get actual block size */
  56.     m = (((long) size) + 5L) & ~1L;        /* calculate new block size */
  57.     if(m <= n)            /* shrink... */
  58.         {
  59.         if((n -= m) >= 8L)        /* big enough to shrink */
  60.             {
  61.             /* calculate new break */
  62.             q = ((long *) (((char *) p) + m));
  63.             p[0] = m;
  64.             *((char *) p) = USED;
  65.             q[0] = n;
  66.             *((char *) q) = USED;
  67.             free(q + 1);        /* free remainder */
  68.             }
  69.         }
  70.     else                    /* grow... */
  71.         {
  72.         d = *(q = ((long *) (((char *) p) + n)));
  73.         if((d > 0) &&            /* next block is free */
  74.            (m <= (n + d)) &&        /* combination is big enough */
  75.            (unlinkblk(q)))        /* block can be unlinked */
  76.                {
  77.             p[0] = (n + d);
  78.             *((char *) p) = USED;    /* extend in place */
  79.             return(realloc(addr, size));
  80.             }
  81.         if(p = ((long *) lalloc(m-4L)))    /* allocate bigger block */
  82.             {
  83.             lmemcpy(p, addr, n-4L);    /* copy old data */
  84.             free(addr);        /* free old block */
  85.             addr = p;
  86.             }
  87.         else
  88.             addr = NULL;
  89.         }
  90.     return(addr);
  91.     }
  92.